package cn.ly.core.concurrent;

import java.util.concurrent.atomic.AtomicInteger;

public class VolatieTest {
	
	//private static volatile int race = 0;
	private static AtomicInteger race = new AtomicInteger();
	
	public static void increase(){
       /**
        * 虽然volatile变量对于多个线程是一致的，但是race++这个语句不是原子性的，这个语句的cpu指令有可能被拆分执行。
        * 此时有可能其它线程又把volatile 变量值增加了，但是当前线程的值还是旧的值，这样结果计算出来就小于预期结果了。
        */
		//race++;               
		race.addAndGet(1); //AtomicInteger的方法都是原子性的，所以能保证线程间的同步性。
	}
	
	private static final int THREADS_COUNT = 20;

	public static void main(String[] args) {
		Thread[] threads = new Thread[THREADS_COUNT];
		for(int i=0; i<THREADS_COUNT; i++){
			threads[i] = new Thread(new Runnable(){
				public void run(){
					for(int i=0; i<1000000; i++){
						increase();
					}
				}
			});
			threads[i].start();
		}
		
		
		
		while(Thread.activeCount() > 1){//返回[当前线程的线程组(是threads[])]中活动线程的数目，轮询的检查当前线程组
			Thread.yield();             //当前线程组，如果有活动线程，则让main主线程暂停，转到其它线程上执行。
			                            /**
			                             * 意思是当前线程暂停执行，让出cpu资源给其它线程，当前线程进入cpu等待队列，此时如果有
			                             * 其它线程执行任务完毕，让出cpu资源，这个线程依然可以去争夺cpu资源，进行执行，
			                             * 所以这里要用while判断它的线程组，如果它再次抢到cpu，而线程组依然有活动线程，
			                             * 则它要再次让出cpu给其它线程，自己等待下次争抢。
			                             * 
			                             * 这里是为了等待子线程运行结束，不如使用join()， 不用写while，也不会去争抢cpu了。
			                             */
		}
		
		System.out.println(race); //预期结果应该是2000000，但是结果小于2000000
	}
	

}
